#include "tachyon/crypto/random/xor_shift/xor_shift_rng.h"

#include "gtest/gtest.h"

namespace tachyon::crypto {

TEST(XORShiftRngTest, NextUint64) {
  uint8_t seed[16] = {
      0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d,
      0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc, 0xe5,
  };
  uint64_t expected[100] = {
      UINT64_C(5719644765813611536),  UINT64_C(14305956443231340292),
      UINT64_C(3482677072762842571),  UINT64_C(7784261772788248241),
      UINT64_C(17253842704833461224), UINT64_C(14239653185454770815),
      UINT64_C(6633452422753404160),  UINT64_C(13090433023660269913),
      UINT64_C(18258063891970645770), UINT64_C(437291729752752195),
      UINT64_C(9212368311569592005),  UINT64_C(1881318862022302859),
      UINT64_C(8121433790281421193),  UINT64_C(9430684813719984921),
      UINT64_C(3743710790114399315),  UINT64_C(7623403977589353428),
      UINT64_C(10689784540225189536), UINT64_C(6314227608983747315),
      UINT64_C(12023216175781001324), UINT64_C(1247429250317392482),
      UINT64_C(15124404311311414102), UINT64_C(3536376116331771714),
      UINT64_C(13372140391163231968), UINT64_C(4627552104030767553),
      UINT64_C(5815810961114836999),  UINT64_C(15198555498458018071),
      UINT64_C(14598705655181811041), UINT64_C(1974664556384156671),
      UINT64_C(16453960414236511979), UINT64_C(14577587862365872550),
      UINT64_C(5307326110650084888),  UINT64_C(17287926254572675193),
      UINT64_C(5814330016395360862),  UINT64_C(908179402052645855),
      UINT64_C(17008011703610211229), UINT64_C(16907694749369302173),
      UINT64_C(9259733836259213201),  UINT64_C(6804200541314624068),
      UINT64_C(15423702039459644860), UINT64_C(15538406174167214534),
      UINT64_C(12642351015120266619), UINT64_C(5734927085045947509),
      UINT64_C(338984259144816760),   UINT64_C(814837196519237940),
      UINT64_C(12092377574622215765), UINT64_C(4929686523249137873),
      UINT64_C(7578938277161758216),  UINT64_C(556715018348158161),
      UINT64_C(18135826653751038349), UINT64_C(2096671650130071344),
      UINT64_C(4878364342165081558),  UINT64_C(6383170428904977100),
      UINT64_C(4034655074585306454),  UINT64_C(430637940813927304),
      UINT64_C(2387870089825088464),  UINT64_C(3614062426512926158),
      UINT64_C(11430717537338432583), UINT64_C(8428449033530022598),
      UINT64_C(5396187671217797056),  UINT64_C(12664192531195519784),
      UINT64_C(186633926847421261),   UINT64_C(5266300151260521672),
      UINT64_C(10751902326511832777), UINT64_C(6123775252746815033),
      UINT64_C(2725770165193166901),  UINT64_C(5410213407606773643),
      UINT64_C(6976963969868509890),  UINT64_C(15795993068178353437),
      UINT64_C(5289892779407555975),  UINT64_C(9038347105216106497),
      UINT64_C(2450746375875507041),  UINT64_C(9878547588967777921),
      UINT64_C(9821024908276872521),  UINT64_C(9756217541011904216),
      UINT64_C(3492661374481453297),  UINT64_C(12987601896609314818),
      UINT64_C(3135698627929260851),  UINT64_C(16051428247861855827),
      UINT64_C(3907579066732945090),  UINT64_C(12261942348272980607),
      UINT64_C(9259426699815884944),  UINT64_C(2078858535711350595),
      UINT64_C(12020280222695588417), UINT64_C(8200866121682790835),
      UINT64_C(1290391369830084283),  UINT64_C(4220890213472660002),
      UINT64_C(14276759160287357654), UINT64_C(18358041331099204300),
      UINT64_C(9110387079659320711),  UINT64_C(2726424275717210332),
      UINT64_C(12193543865555892126), UINT64_C(13979317448342616273),
      UINT64_C(15589337403047049790), UINT64_C(5042850533273272111),
      UINT64_C(5598077207033268956),  UINT64_C(8557810207710613009),
      UINT64_C(9318823210973686820),  UINT64_C(7879556961278080875),
      UINT64_C(4115505420980006796),  UINT64_C(16660106575296596679),
  };

  XORShiftRNG rng;
  ASSERT_TRUE(rng.SetSeed(seed));
  for (size_t i = 0; i < 100; ++i) {
    EXPECT_EQ(rng.NextUint64(), expected[i]);
  }
}

}  // namespace tachyon::crypto
